package mrt.cse.tempworks.initialWorksOfTeamMembers.ishara;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: isha
 * Date: 1/24/12
 * Time: 8:41 PM
 * To change this template use File | Settings | File Templates.
 */
public class ManagementSystemControl implements Watcher{

    private static final Logger logger = LoggerFactory
            .getLogger(ManagementSystemControl.class);

    private ZooKeeper zooKeeper = null;
    private String zkServerAddress;
    private String coordinatorPath ;
    private byte [] coordinatorData = {5};
    private List<ACL> ACLlist = new ArrayList<ACL>();
    private ACL acl = new ACL(5,new Id("ip","127.0.0.1"));
    private Map<String,Integer> nodeIDS= new HashMap<String,Integer>();


    public ManagementSystemControl(String zkServerAddress) throws IOException, InterruptedException, KeeperException {
        this.zkServerAddress = zkServerAddress;

        if(zooKeeper==null){
           zooKeeper = new ZooKeeper(zkServerAddress,3000,this);
        }

        coordinatorPath = "/COORDINATOR";
        ACLlist.add(acl);
        zooKeeper.create(coordinatorPath,coordinatorData,ACLlist, CreateMode.PERSISTENT );
        createNodes(coordinatorPath);
        printNodes(zooKeeper);
        List<Manager> managers = sortManagers(zooKeeper);
        leaderElection();
        zooKeeper.delete(managers.get(1).getnodePath(), 1, null, null);

        
    }

    private void leaderElection() throws InterruptedException, KeeperException {

        List<Manager> managerList = sortManagers(zooKeeper);
        for (Manager manager : managerList) {
            if (manager.getSequenceID() == 0) {
                System.out.println("I am the leader :" + manager.getName());
                logger.info("Current Leader is :" + manager.getName());
            }
            else {
                becomeReady(manager);
            }

        }
    }

    private void becomeReady(Manager manager) {


    }

    private void createNodes(String coordinatorPath) throws InterruptedException, KeeperException {

        //for(int i=0; i< 5; i++){
        Manager manager1 =  new Manager();
        manager1.setnodePath(zooKeeper.create(coordinatorPath + "/n_", coordinatorData, ACLlist , CreateMode.EPHEMERAL_SEQUENTIAL));
        Manager manager2 =  new Manager();
        manager2.setnodePath(zooKeeper.create(coordinatorPath + "/n_", coordinatorData, ACLlist , CreateMode.EPHEMERAL_SEQUENTIAL));
        Manager manager4 =  new Manager();
        manager4.setnodePath(zooKeeper.create(coordinatorPath + "/n_", coordinatorData, ACLlist , CreateMode.EPHEMERAL_SEQUENTIAL));
        //}

    }

    private void printNodes(ZooKeeper zooKeeper) throws InterruptedException, KeeperException {
        List<String> childnodes = zooKeeper.getChildren(coordinatorPath , true);
        for(String node : childnodes){
            System.out.println(node);
        }

    }

    private List<Manager> sortManagers(ZooKeeper zooKeeper) throws InterruptedException, KeeperException {

        List<String> childnodes = zooKeeper.getChildren(coordinatorPath , true);
        List<Manager> managers = new ArrayList<Manager>(childnodes.size());


        for(String node : childnodes){
            String name = new String(zooKeeper.getData(
                    coordinatorPath + "/" + node, false, null));
            Manager manager = new Manager(Integer.valueOf(node.substring("n_"
                    .length())), coordinatorPath + "/" + node, name) ;
            managers.add(manager);
            Collections.sort(managers, new Manager.SequenceIDComparator() );

            System.out.println(manager.getSequenceID()+ " :" +  manager.getnodePath()+ " :" +  manager.getName());

        }
        return managers;
    }
    @Override
    public void process(WatchedEvent event) {
        if(event.getType().equals(Watcher.Event.EventType.NodeDeleted)){
            logger.info("Node deleted : refinding the leader now");
            System.out.println("deleted");
             try{
                leaderElection();
             } catch (InterruptedException e) {
                 e.printStackTrace();
             } catch (KeeperException e) {
                 e.printStackTrace();
             }
        }
    }
}
